home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / a_utils / perl / perl5a1.lha / perl5alpha1 / do / match < prev    next >
Encoding:
Text File  |  1992-08-15  |  6.3 KB  |  289 lines

  1. int
  2. do_match(TARG,arg,gimme,arglast)
  3. STR *TARG;
  4. register ARG *arg;
  5. int gimme;
  6. int *arglast;
  7. {
  8.     register STR **st = stack->ary_array;
  9.     register SPAT *spat = arg[2].arg_ptr.arg_spat;
  10.     register char *t;
  11.     register int sp = arglast[0] + 1;
  12.     STR *srchstr = st[sp];
  13.     register char *s = str_get(st[sp]);
  14.     char *strend = s + st[sp]->str_cur;
  15.     STR *tmpstr;
  16.     char *myhint = hint;
  17.     int global;
  18.     int safebase;
  19.     char *truebase = s;
  20.     register REGEXP *rx = spat->spat_regexp;
  21.  
  22.     hint = Nullch;
  23.     if (!spat) {
  24.     if (gimme == G_ARRAY)
  25.         return --sp;
  26.     str_set(TARG,Yes);
  27.     STABSET(TARG);
  28.     st[sp] = TARG;
  29.     return sp;
  30.     }
  31.     global = spat->spat_flags & SPAT_GLOBAL;
  32.     safebase = (gimme == G_ARRAY) || global;
  33.     if (!s)
  34.     fatal("panic: do_match");
  35.     if (spat->spat_flags & SPAT_USED) {
  36. #ifdef DEBUGGING
  37.     if (debug & 8)
  38.         deb("2.SPAT USED\n");
  39. #endif
  40.     if (gimme == G_ARRAY)
  41.         return --sp;
  42.     str_set(TARG,No);
  43.     STABSET(TARG);
  44.     st[sp] = TARG;
  45.     return sp;
  46.     }
  47.     --sp;
  48.     if (spat->spat_runtime) {
  49.     nointrp = "|)";
  50.     sp = eval(spat->spat_runtime,G_SCALAR,sp);
  51.     st = stack->ary_array;
  52.     t = str_get(tmpstr = st[sp--]);
  53.     nointrp = "";
  54. #ifdef DEBUGGING
  55.     if (debug & 8)
  56.         deb("2.SPAT /%s/\n",t);
  57. #endif
  58.     if (!global && rx)
  59.         regfree(rx);
  60.     spat->spat_regexp = Null(REGEXP*);    /* crucial if regcomp aborts */
  61.     spat->spat_regexp = regcomp(t,t+tmpstr->str_cur,
  62.         spat->spat_flags & SPAT_FOLD);
  63.     if (!spat->spat_regexp->prelen && lastspat)
  64.         spat = lastspat;
  65.     if (spat->spat_flags & SPAT_KEEP) {
  66.         if (!(spat->spat_flags & SPAT_FOLD))
  67.         scanconst(spat,spat->spat_regexp->precomp,
  68.             spat->spat_regexp->prelen);
  69.         if (spat->spat_runtime)
  70.         arg_free(spat->spat_runtime);    /* it won't change, so */
  71.         spat->spat_runtime = Nullarg;    /* no point compiling again */
  72.         hoistmust(spat);
  73.         if (curcmd->c_expr && (curcmd->c_flags & CF_OPTIMIZE) == CFT_EVAL) {
  74.         curcmd->c_flags &= ~CF_OPTIMIZE;
  75.         opt_arg(curcmd, 1, curcmd->c_type == C_EXPR);
  76.         }
  77.     }
  78.     if (global) {
  79.         if (rx) {
  80.             if (rx->startp[0]) {
  81.             s = rx->endp[0];
  82.             if (s == rx->startp[0])
  83.             s++;
  84.             if (s > strend) {
  85.             regfree(rx);
  86.             rx = spat->spat_regexp;
  87.             goto nope;
  88.             }
  89.         }
  90.         regfree(rx);
  91.         }
  92.     }
  93.     else if (!spat->spat_regexp->nparens)
  94.         gimme = G_SCALAR;            /* accidental array context? */
  95.     rx = spat->spat_regexp;
  96.     if (regexec(rx, s, strend, s, 0,
  97.       srchstr->str_pok & SP_STUDIED ? srchstr : Nullstr,
  98.       safebase)) {
  99.         if (rx->subbase || global)
  100.         curspat = spat;
  101.         lastspat = spat;
  102.         goto gotcha;
  103.     }
  104.     else {
  105.         if (gimme == G_ARRAY)
  106.         return sp;
  107.         str_sset(TARG,&str_no);
  108.         STABSET(TARG);
  109.         st[++sp] = TARG;
  110.         return sp;
  111.     }
  112.     }
  113.     else {
  114. #ifdef DEBUGGING
  115.     if (debug & 8) {
  116.         char ch;
  117.  
  118.         if (spat->spat_flags & SPAT_ONCE)
  119.         ch = '?';
  120.         else
  121.         ch = '/';
  122.         deb("2.SPAT %c%s%c\n",ch,rx->precomp,ch);
  123.     }
  124. #endif
  125.     if (!rx->prelen && lastspat) {
  126.         spat = lastspat;
  127.         rx = spat->spat_regexp;
  128.     }
  129.     t = s;
  130.     play_it_again:
  131.     if (global && rx->startp[0]) {
  132.         t = s = rx->endp[0];
  133.         if (s == rx->startp[0])
  134.         s++,t++;
  135.         if (s > strend)
  136.         goto nope;
  137.     }
  138.     if (myhint) {
  139.         if (myhint < s || myhint > strend)
  140.         fatal("panic: hint in do_match");
  141.         s = myhint;
  142.         if (rx->regback >= 0) {
  143.         s -= rx->regback;
  144.         if (s < t)
  145.             s = t;
  146.         }
  147.         else
  148.         s = t;
  149.     }
  150.     else if (spat->spat_short) {
  151.         if (spat->spat_flags & SPAT_SCANFIRST) {
  152.         if (srchstr->str_pok & SP_STUDIED) {
  153.             if (screamfirst[spat->spat_short->str_rare] < 0)
  154.             goto nope;
  155.             else if (!(s = screaminstr(srchstr,spat->spat_short)))
  156.             goto nope;
  157.             else if (spat->spat_flags & SPAT_ALL)
  158.             goto yup;
  159.         }
  160. #ifndef lint
  161.         else if (!(s = fbminstr((unsigned char*)s,
  162.           (unsigned char*)strend, spat->spat_short)))
  163.             goto nope;
  164. #endif
  165.         else if (spat->spat_flags & SPAT_ALL)
  166.             goto yup;
  167.         if (s && rx->regback >= 0) {
  168.             ++spat->spat_short->str_u.str_useful;
  169.             s -= rx->regback;
  170.             if (s < t)
  171.             s = t;
  172.         }
  173.         else
  174.             s = t;
  175.         }
  176.         else if (!multiline && (*spat->spat_short->str_ptr != *s ||
  177.           bcmp(spat->spat_short->str_ptr, s, spat->spat_slen) ))
  178.         goto nope;
  179.         if (--spat->spat_short->str_u.str_useful < 0) {
  180.         str_free(spat->spat_short);
  181.         spat->spat_short = Nullstr;    /* opt is being useless */
  182.         }
  183.     }
  184.     if (!rx->nparens && !global) {
  185.         gimme = G_SCALAR;            /* accidental array context? */
  186.         safebase = FALSE;
  187.     }
  188.     if (regexec(rx, s, strend, truebase, 0,
  189.       srchstr->str_pok & SP_STUDIED ? srchstr : Nullstr,
  190.       safebase)) {
  191.         if (rx->subbase || global)
  192.         curspat = spat;
  193.         lastspat = spat;
  194.         if (spat->spat_flags & SPAT_ONCE)
  195.         spat->spat_flags |= SPAT_USED;
  196.         goto gotcha;
  197.     }
  198.     else {
  199.         if (global)
  200.         rx->startp[0] = Nullch;
  201.         if (gimme == G_ARRAY)
  202.         return sp;
  203.         str_sset(TARG,&str_no);
  204.         STABSET(TARG);
  205.         st[++sp] = TARG;
  206.         return sp;
  207.     }
  208.     }
  209.     /*NOTREACHED*/
  210.  
  211.   gotcha:
  212.     if (gimme == G_ARRAY) {
  213.     int iters, i, len;
  214.  
  215.     iters = rx->nparens;
  216.     if (global && !iters)
  217.         i = 1;
  218.     else
  219.         i = 0;
  220.     if (sp + iters + i >= stack->ary_max) {
  221.         astore(stack,sp + iters + i, Nullstr);
  222.         st = stack->ary_array;        /* possibly realloced */
  223.     }
  224.  
  225.     for (i = !i; i <= iters; i++) {
  226.         st[++sp] = str_mortal(&str_no);
  227.         /*SUPPRESS 560*/
  228.         if (s = rx->startp[i]) {
  229.         len = rx->endp[i] - s;
  230.         if (len > 0)
  231.             str_nset(st[sp],s,len);
  232.         }
  233.     }
  234.     if (global) {
  235.         truebase = rx->subbeg;
  236.         goto play_it_again;
  237.     }
  238.     return sp;
  239.     }
  240.     else {
  241.     str_sset(TARG,&str_yes);
  242.     STABSET(TARG);
  243.     st[++sp] = TARG;
  244.     return sp;
  245.     }
  246.  
  247. yup:
  248.     ++spat->spat_short->str_u.str_useful;
  249.     lastspat = spat;
  250.     if (spat->spat_flags & SPAT_ONCE)
  251.     spat->spat_flags |= SPAT_USED;
  252.     if (global) {
  253.     rx->subbeg = t;
  254.     rx->subend = strend;
  255.     rx->startp[0] = s;
  256.     rx->endp[0] = s + spat->spat_short->str_cur;
  257.     curspat = spat;
  258.     goto gotcha;
  259.     }
  260.     if (sawampersand) {
  261.     char *tmps;
  262.  
  263.     if (rx->subbase)
  264.         Safefree(rx->subbase);
  265.     tmps = rx->subbase = nsavestr(t,strend-t);
  266.     rx->subbeg = tmps;
  267.     rx->subend = tmps + (strend-t);
  268.     tmps = rx->startp[0] = tmps + (s - t);
  269.     rx->endp[0] = tmps + spat->spat_short->str_cur;
  270.     curspat = spat;
  271.     }
  272.     str_sset(TARG,&str_yes);
  273.     STABSET(TARG);
  274.     st[++sp] = TARG;
  275.     return sp;
  276.  
  277. nope:
  278.     rx->startp[0] = Nullch;
  279.     if (spat->spat_short)
  280.     ++spat->spat_short->str_u.str_useful;
  281.     if (gimme == G_ARRAY)
  282.     return sp;
  283.     str_sset(TARG,&str_no);
  284.     STABSET(TARG);
  285.     st[++sp] = TARG;
  286.     return sp;
  287. }
  288.  
  289.